package com.etone.smartAudit.codeMaker;

import com.etone.smartAudit.utils.DateUtil;
import com.etone.smartAudit.utils.StringUtil;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author: sovy
 * @date: 2019/6/1
 * @description:
 */
public class CodeMaker {
    private Configuration cfg = new Configuration(Configuration.getVersion());

    private List<FileType> fileTypes = new ArrayList<>();

    public CodeMaker() {
        cfg.setClassForTemplateLoading(this.getClass(), Config.templetePath);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLogTemplateExceptions(true);
        cfg.setObjectWrapper(new DefaultObjectWrapper(Configuration.getVersion()));
    }


    /**
     * 开始运行,生成全部文件
     *
     * @param fileName
     */
    public static void run(String fileName) {
        CodeMaker codeMaker = new CodeMaker();
        codeMaker.fileTypes = Arrays.asList(FileType.values());
        codeMaker.start(fileName);
    }

    /**
     * 开始运行,生成指定文件
     *
     * @param fileName
     */
    public static void run(String fileName, FileType fileType) {
        CodeMaker codeMaker = new CodeMaker();
        codeMaker.fileTypes = Arrays.asList(fileType);
        codeMaker.start(fileName);
    }

    /**
     * 开始运行,生成部分文件
     *
     * @param fileName
     */
    public static void run(String fileName, List<FileType> fileTypes) {
        CodeMaker codeMaker = new CodeMaker();
        codeMaker.fileTypes = fileTypes;
        codeMaker.start(fileName);
    }

    private void start(String fileName) {
        fileTypes.forEach(fileType -> {
            writeFile(fileName, fileType);
        });
    }

    /**
     * 生成文件
     *
     * @param fileName
     * @param fileType
     */
    private void writeFile(String fileName, FileType fileType) {
        fileName = StringUtil.upperFistChar(fileName);
        String module = Config.commonModuleFile.contains(fileType) ? Config.commonModuleName : Config.moduleName;
        String date = DateUtil.turnJavaUtilDateToStrDate(new Date(), DateUtil.DF_yyyy_MM_dd_HH_mm_ss);
        DataModel model = DataModel
                .builder()
                .createTime(date)
                .basePackage(Config.packageName)
                .methodName(fileName)
                .defineName(StringUtil.lowerFistChar(fileName))
                .build();
        String realFileName;
        switch (fileType) {
            case DOMAIN:
                realFileName = fileName;
                break;
            case VO:
            case DTO:
                realFileName = fileName + fileType.toString();
                break;
            default:
                realFileName = fileName + StringUtil.upperFistChar(fileType.toString().toLowerCase());
        }

        String outFilePath = "./" + module + "/src/main/java/" + Config.packageName.replaceAll("\\.", "/") + "/" + fileType.toString().toLowerCase() + "/" + realFileName + ".java";
        File outFile = new File(outFilePath);
        if (outFile.exists() && !Config.overWrit) {
            return;
        }
        if (!outFile.getParentFile().isDirectory()) {
            outFile.getParentFile().mkdir();
        }
        try {
            Template temp = cfg.getTemplate(fileType.toString().toLowerCase() + ".java.ftl");
            FileWriter writer = new FileWriter(outFile);

            temp.process(model, writer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
